#include "rc4.h"

namespace yc {
namespace rc4 {

void init(unsigned char s[256], const unsigned char* key, int len)
{
    int i = 0, j = 0;
    unsigned char k[256] = { 0 };
    unsigned char tmp = 0;
    for (i = 0; i < 256; i++) {
        s[i] = i;
        k[i] = key[i % len];
    }
    for (i = 0; i < 256; i++) {
        j = (j + s[i] + k[i]) % 256;
        tmp = s[i];
        s[i] = s[j]; // 交换s[i]和s[j]
        s[j] = tmp;
    }
}

void encrypt(unsigned char s[256], unsigned char* data, int len)
{
    int i = 0, j = 0, t = 0;
    unsigned char tmp;
    for (int k = 0; k < len; k++) {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        tmp = s[i];
        s[i] = s[j]; // 交换s[x]和s[y]
        s[j] = tmp;
        t = (s[i] + s[j]) % 256;
        data[k] ^= s[t];
    }
}

QByteArray crypt(const QByteArray& data, const QByteArray& key)
{
    QByteArray result(data);
    if (!data.isEmpty()) {
        unsigned char s[256];
        rc4::init(s, reinterpret_cast<const unsigned char*>(key.data()), key.size());
        rc4::encrypt(s, reinterpret_cast<unsigned char*>(result.data()), result.size());
    }
    return result.toBase64(QByteArray::Base64Encoding);
}

QByteArray decrypt(const QByteArray& data, const QByteArray& key)
{
    QByteArray result = QByteArray::fromBase64(data, QByteArray::Base64Encoding);
    if (!data.isEmpty()) {
        unsigned char s[256];
        rc4::init(s, reinterpret_cast<const unsigned char*>(key.data()), key.size());
        rc4::encrypt(s, reinterpret_cast<unsigned char*>(result.data()), result.size());
    }
    return result;
}

} // namespace rc4
} // namespace yc
